﻿using Game.Assets.Scripts.Manager;
using Game.UI;
using QFramework;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using UnityEngine;
using cfg;
using Game.Assets.Scripts.Model;
using Game.CheseBoard.Data;

namespace Game.System.CheseBoard
{
    internal class ChessSystem : AbstractSystem
    {

        ChessModel chessboardModel;
        TableManager table;
        protected override void OnInit()
        {
            chessboardModel = this.GetModel<ChessModel>();
            table = this.GetModel<TableManager>();
            Debug.Log("ChessSystem");
        }

        public void CreatInitPiece()
        {
            for (int i = 0; i < table.Tables.TbInitialState.DataList.Count; i++)
            {
                int[] temp = Array.ConvertAll(table.Tables.TbInitialState.DataList[i].BoardCoordinate.Replace("(", "").Replace(")", "").Split(','), int.Parse);
                (int x, int y) pos = (temp[1] - 1, temp[0] - 1);
                chessboardModel.SetData(pos.x, pos.y, table.Tables.TbPiece.Get(table.Tables.TbInitialState.DataList[i].BoardStartpiece));
                TypeEventSystem.Global.Send(new PieceToCheseBoardEvent() { cellData = table.Tables.TbInitialState.DataList[i].BoardStartpiece, pos = pos });
            }

        }

        /// <summary>
        /// 放入一个棋子到棋盘（从缓存区）
        /// </summary>
        /// <param name="piece"></param>
        public void PutInPiece(int piece)
        {
            if (piece == -1) return;

            (int, int) pos = FindFirstNullGrid();
            if (pos == (-1, -1))
            {
                Debug.Log("棋盘已满");
                return;
            }
            chessboardModel.SetData(pos.Item1, pos.Item2, table.Tables.TbPiece.Get(piece));
            this.GetModel<BufferModel>().PopData();
            TypeEventSystem.Global.Send(new PieceToCheseBoardEvent() { cellData = piece, pos = pos });
        }
        /// <summary>
        /// 放入一个棋子到棋盘（从背包）
        /// </summary>
        /// <param name="piece"></param>
        public void PutInPiece(BaseCell piece)
        {
            if (piece == null) return;

            (int, int) pos = FindFirstNullGrid();
            if (pos == (-1, -1))
            {
                Debug.Log("棋盘已满");
                return;
            }
            chessboardModel.SetData(pos.Item1, pos.Item2, piece.Piece);
            TypeEventSystem.Global.Send(new BagToCheseBoardEvent() { cellData = piece, pos = pos });
        }
        /// <summary>
        /// 放入一个棋子到棋盘（某个坐标向四周）
        /// </summary>
        /// <param name="piece"></param>
        public void PutInPiece(int piece, (int x, int y) centre, int maxPlies = ChessModel.ROW)
        {
            if (piece == -1) return;

            (int x, int y) pos = FindAroundNullGrid(centre, 0, maxPlies);
            if (pos == (-1, -1))
            {
                Debug.Log("棋盘已满");
                return;
            }
            chessboardModel.SetData(pos.x, pos.y, table.Tables.TbPiece.Get(piece));
            TypeEventSystem.Global.Send(new PieceToCheseBoardEvent() { cellData = piece, pos = pos });
        }

        /// <summary>
        /// 出售棋子
        /// </summary>
        /// <param name="pos"></param>
        public void SellPiece((int x, int y) pos)
        {
            chessboardModel.RemovePiece(pos);
            //TODO 消息？货币？
            TypeEventSystem.Global.Send(new SellPieceSucceedEvent() { pos = pos });
        }

        public void GetNearbyPos((int x, int y) centre)
        {
            List<(int, int)> posList = new List<(int, int)>();
            GetAroundGridOffset(0, out int[] x, out int[] y);
            for (int i = 0; i < x.Length; i++)
            {
                //避免越界
                if (centre.x + x[i] < 0 || centre.x + x[i] >= ChessModel.ROW
                    || centre.y + y[i] < 0 || centre.y + y[i] >= ChessModel.COL)
                {
                    continue;
                }
                posList.Add((centre.x + x[i], centre.y + y[i]));
            }

            TypeEventSystem.Global.Send(new GetNearbyPosEvent() { posList = posList });
        }

        /// <summary>
        /// 找出从左上角开始第一个空格子
        /// </summary>
        /// <returns></returns>
        (int, int) FindFirstNullGrid()
        {
            for (int i = 0; i < ChessModel.ROW; i++)
            {
                for (int j = 0; j < ChessModel.COL; j++)
                {
                    if (chessboardModel.Chessboard[i, j] == null)
                    {
                        return (i, j);
                    }
                }
            }
            return (-1, -1);
        }

        /// <summary>
        /// 在周围找一个空格子
        /// </summary>
        /// <param name="centre">中心</param>
        /// <param name="plies">开始层数(从0开始)</param>
        /// <param name="maxPlies"><最大层数/param>
        /// <returns></returns>
        (int, int) FindAroundNullGrid((int x, int y) centre, int plies, int maxPlies)
        {
            do
            {
                GetAroundGridOffset(plies, out int[] x, out int[] y);
                for (int i = 0; i < x.Length; i++)
                {
                    //避免越界
                    if (centre.x + x[i] < 0 || centre.x + x[i] >= ChessModel.ROW
                        || centre.y + y[i] < 0 || centre.y + y[i] >= ChessModel.COL)
                    {
                        continue;
                    }
                    if (chessboardModel.Chessboard[centre.x + x[i], centre.y + y[i]] == null)
                    {
                        return (centre.x + x[i], centre.y + y[i]);
                    }
                }
                plies++;
            } while (plies < maxPlies);


            return (-1, -1);
        }
        /// <summary>
        /// 获取周围格子的偏移量
        /// </summary>
        /// <param name="plies"></param>
        void GetAroundGridOffset(int plies, out int[] x, out int[] y)
        {
            plies = plies + 1;
            List<int> yList = new List<int>();
            List<int> xList = new List<int>();
            //上（右侧）
            for (int i = 0; i <= plies; i++)
            {
                yList.Add(i);
                xList.Add(-plies);
            }
            //右
            for (int i = 0; i < plies * 2; i++)
            {
                yList.Add(plies);
                xList.Add(-plies + i + 1);

            }
            //下
            for (int i = 0; i < plies * 2; i++)
            {
                yList.Add(plies - (i + 1));
                xList.Add(plies);
            }
            //左
            for (int i = 0; i < plies * 2; i++)
            {
                yList.Add(-plies);
                xList.Add(plies - (i + 1));
            }
            //上（左侧）
            for (int i = 0; i < plies - 1; i++)
            {
                yList.Add(-plies + i + 1);
                xList.Add(-plies);
            }
            y = yList.ToArray();
            x = xList.ToArray();
        }
    }
}
